由於ASP.NET Core 架構上大量地使用依賴注入(Dependency Injection)處理服務物件的傳遞,這確實讓學習難度提高了,算是半強迫性的學習新知識吧,但我認為這是好的。那接下來就來介紹一下究竟為什麼ASP.NET Core要放進這些鬼東西?到底有那些好處呢?
什麼是 IoC (Inversion of Control,控制反轉) ?
用來減低電腦代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡稱DI)
例如:「模組都必須依賴於抽象」是 IoC 的一種表現,「實現必須依賴抽象,而不是抽象依賴實現」也是 IoC 的一種表現
什麼是 DI (Dependency Injection,依賴注入)?
DI 是指將一個程式的相依關係改由呼叫它的外部程式來決定的方法。
保留抽象介面,讓組件依賴於抽象介面,當組件要與其它實際的物件發生依賴關係時,藉過抽象介面來注入依賴的實際物件。
使用 DI 的好處
- 低耦合,高內聚
- 更清晰的意圖
- 降低邏輯變更造成改動程式碼的幅度
- 關注點分離,提高可測試性
使用 DI 的缺點
系統架構的複雜度增加:我們在寫Code時經常依賴IDE查找引用的功能,對不了解的新手來說,可能會發生找不到實際邏輯到底寫在哪裡的情況,需要多花時間來熟悉框架流程才能上手。
如何注入?
常見的注入方式大約可以分為下列三種:
1. Interface injection
2. Setter injection
3. Constructor injection
假設我們有一個功能,需要拿取得所有使用者的資料,我們可能會寫成如下:
1 | public class UserController : Controller |
然後我們嘗試將new拿掉,改用注入的方式,就可以變成這樣:
1 | public class UserController : Controller |
接下來,依照不同的DI Framework,注入UserRepository實際的Instance即可。
C#常見的DI Framework
ASP.NET Core 中的注入
ASP.NET Core 的架構基於DI之上,如果從.NET Framework跳到 .Net Core 的話,DI的學習是必經之路。
然而 ASP.NET Core 的 DI 是採用 Interface injection
+ Constructor Injection
在 Startup.ConfigureServices中,
我們可以註冊三種不同的選項:
1. Singleton
整個 Process 只建立一個 Instance,任何時候都共用它。
2. Scoped
在網頁 Request 處理過程(指接到瀏覽器請求到回傳結果前的執行期間)共用一個 Instance。
3. Transient
每次要求就建立一個新的,永不共用。
下面是三種選項的註冊方式,依照不同的情境選一種使用即可,通常最常使用的是Scoped。
Startup.cs
1 | public void ConfigureServices(IServiceCollection services) |
註冊完我們就可以再Controller中使用囉
UserController.cs
1 | public class UserController : Controller |
心得
其實在職場中待久了,經常會看見一些專案會使用DI的Framework,但又或許是因為交接不完全和開發者參差不齊的原因,經果一陣子了人員調動後,專案常常就會有四不像的情形發生,有些地方用了DI,又有些地方總是一直在new物件。希望這篇能讓新手了解一些觀念,往後看到DI的東西也不太恐懼,先多看看文件在動手吧!別破壞了原有的好架構。
參考
ASP.NET Core Dependency Injection Deep Dive
街口支付
街口帳號: 901061546